package com.fx.attendance.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fx.attendance.ai.AiFaceTemplate;
import com.fx.attendance.domain.FaceInformation;
import com.fx.attendance.dto.FaceInformationQueryCriteria;
import com.fx.attendance.enums.ResultEnum;
import com.fx.attendance.exception.ApiException;
import com.fx.attendance.repository.FaceInfomationRepository;
import com.fx.attendance.service.FaceInformationService;
import com.fx.utils.*;
import org.springframework.transaction.annotation.Transactional;
import com.fx.domain.system.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.data.domain.Page;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;


/**
 * @version: 1.0
 * @author: lijie
 * @date 2020-06-29
 */
@Service
@Slf4j
public class FaceInformationServiceImpl implements FaceInformationService {


    @Autowired(required = false)
    private AiFaceTemplate aiFaceTemplate;
    @Autowired
    private FaceInfomationRepository faceInfomationRepository;

    @Override
    public Map<String,Object> queryAll(FaceInformationQueryCriteria criteria, Pageable pageable){
        Page<FaceInformation> page = faceInfomationRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.getContent(),page.getTotalElements());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FaceInformation create(FaceInformation resources) {
        return faceInfomationRepository.save(resources);
    }

    @Override
    public List<FaceInformation> queryAll(FaceInformationQueryCriteria criteria){
        return faceInfomationRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(FaceInformation resources) {
        FaceInformation faceInformation = faceInfomationRepository.findById(resources.getId()).orElseGet(FaceInformation::new);
        ValidationUtil.isNull( faceInformation.getId(),"FaceInformation","id",resources.getId());
        faceInformation.copy(resources);
        faceInfomationRepository.save(faceInformation);
    }

    @Override
    public void deleteAll(Long[] ids) {
        for (Long id : ids) {
            faceInfomationRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<FaceInformation> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (FaceInformation faceInformation : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put(" createBy",  faceInformation.getCreateBy());
            map.put(" createTime",  faceInformation.getCreateTime());
            map.put(" updateTime",  faceInformation.getUpdateTime());
            map.put(" updateBy",  faceInformation.getUpdatedBy());
            map.put(" faceContent",  faceInformation.getFaceContent());
            map.put(" guid",  faceInformation.getGuid());
            map.put(" standardScore",  faceInformation.getStandardScore());
            map.put(" validFlag",  faceInformation.getValidFlag());
            map.put(" userId",  faceInformation.getUser().getUsername());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public JSONObject checkFace(MultipartFile file, String compareId) throws Exception {
        return JSON.parseObject(aiFaceTemplate.checkFace(file,compareId));
    }

    @Override
    public JSONObject serachFace(MultipartFile file) throws Exception {
        return JSON.parseObject(this.aiFaceTemplate.searchFace(file));
    }

    @Override
    public JSONObject checkFace(String base64Img, String userId) throws ApiException {
        FaceInformation faceInformation=faceInfomationRepository.findByUserId(userId);
        Date date=new Date();
        if (faceInformation==null){
            throw new ApiException(ResultEnum.CUSTOMFAILURE,"当前人脸库中并无你的信息，请联系管理员采集人脸");
        }
        JSONObject res= JSON.parseObject(aiFaceTemplate.compareWithTwoImh(new String(faceInformation.getFaceContent()),base64Img));
        if (!ValidUtil.isEmptyOrNull(res.getInteger("error_code")) && res.getInteger("error_code").equals(223114)){
            throw new ApiException(ResultEnum.CUSTOMFAILURE,"图像模糊,人脸识别失败");
        }
        if (!ValidUtil.isEmptyOrNull(res.getInteger("error_code")) && res.getInteger("error_code").equals(222207)){
            throw new ApiException(ResultEnum.CUSTOMFAILURE,"找不到匹配的人脸");
        }
        if (res.getInteger("error_code")==0 &&  !ValidUtil.isEmptyOrNull(res.getJSONObject("result"))){
            BigDecimal bigDecimal=res.getJSONObject("result").getBigDecimal("score");
            int standard=faceInformation.getStandardScore();
            if (bigDecimal.intValue()>=standard){
                //验证成功

            }else{
                throw  new ApiException(ResultEnum.CUSTOMFAILURE,"匹配失败,建议调整比分阈值");
            }

        }
        return res;
    }

    @Override
    public List<Map<String, Object>> getALlFaces() throws Exception {
        /*List<Map<String,Object>> result=this.baseDao.getALlFaces();
        result=result.stream().peek(data->{
            if (!ValidUtil.isEmptyOrNull(data.get("guid"))){
                data.put("faceContent",new String((byte[])data.get("faceContent")));
            }

        }).collect(Collectors.toList());*/
        return null;
    }

    @Override
    public void addFace(Map<String, Object> param) throws Exception {
        byte[] faceContent=param.get("faceContent").toString().getBytes("utf-8");
        String userId=param.get("userId").toString();
        User user=faceInfomationRepository.getUserById(userId);
        if (faceInfomationRepository.findByUserId(userId)==null){
            throw new ApiException(ResultEnum.CUSTOMFAILURE,"不存在此用户");
        }
        int standardScore=Integer.valueOf(param.get("standardScore").toString());
        FaceInformation faceInformation=faceInfomationRepository.findByUserId(userId);
        if (faceInformation==null){
            faceInformation=new FaceInformation();
        }
        faceInformation.setGuid(UUID.randomUUID().toString());
        faceInformation.setFaceContent(faceContent);
        faceInformation.setStandardScore(standardScore);
        faceInfomationRepository.saveAndFlush(faceInformation);
    }

}
